package layers.agents;

import java.util.ArrayList;

import layers.ants.ExplorationAnt;
import layers.ants.IntentionAnt;
import layers.physical.Crossroad;
import layers.physical.Path;
import events.truckEvents.TruckEndedSearchingPackageEvent;
import events.truckEvents.TruckStartedSearchingPackageEvent;
import framework.events.EventBroker;

public class TruckAgentStateCreatingIntention extends TruckAgentState {


	/**
	 * Ticks left until next batch of ants is sent out 
	 */
	private int ticksLeft = 0;
	public ArrayList<Path> rejectedPaths = new ArrayList<Path>();
	private boolean changeState = false;
	private Path acceptedPath = null;
	private int hops = ExplorationAnt.INITIALHOPS;
	private boolean firstTime = true;

	public TruckAgentStateCreatingIntention(TruckAgent agent) {
		super(agent);
	}

	/**
	 * Exploration ants blijven uitsturen tot er eentje een pakket heeft gevonden. Wanneer er dan een pad gevonden
	 * is, intention ant uitsturen en van state veranderen.
	 */
	protected void processTick(){
		if(firstTime){
			EventBroker.getEventBroker().notifyAll(new TruckStartedSearchingPackageEvent(this.getAgent().getTruck()));
			firstTime = false;
		}
		if(!this.getAgent().getTruck().isOnConnector())
			this.getAgent().ensureIsOnCrossRoad();
		else{
			if(changeState){
				this.getAgent().clearPaths();
				this.getAgent().setState(new TruckAgentStateExecutingIntention(getAgent(),acceptedPath.getClone()));
				EventBroker.getEventBroker().notifyAll(new TruckEndedSearchingPackageEvent(this.getAgent().getTruck()));
				this.clearAgent();
			}else if(this.getTicksLeft() == 0){
				newIteration();
			}
			this.decreaseTicksLeft();
		}
	}



	private void newIteration() {
		Path path = getIntention();
		Crossroad currentCrossroad = this.getAgent().getTruck().getConnectorPosition().getConnector();
		if(path != null){
			//Er is een exploration ant die een pakketje heeft gevonden
			//System.out.println("Truck "+ this.getAgent().getId() + " found package");
			new IntentionAnt(currentCrossroad, getAgent(), path.getClone());
			this.resetTicksLeft();
		}else{
			//Geen pakketje gevonden, radius vergroten en nieuwe exploration ant uitsturen
			this.increaseHops();
			new ExplorationAnt(currentCrossroad, getAgent(), this.getHops(), 0, null);
			this.resetTicksLeft();
		}
	}

	private Path getIntention() {
		boolean refused = true;
		Path path = null;
		if(this.getAgent().getPaths().size() == 0)
			return null;
		while(refused && this.getAgent().getPaths().size() > 0){
			path = this.getAgent().getBestPath();
			this.getAgent().getPaths().remove(path);
			if(!matchesRejected(path))
				refused = false;
		}
		return path;
	}


	private boolean matchesRejected(Path path){
		return path.pathInList(rejectedPaths);
	}


	public void setRoute(ArrayList<Crossroad> route){
		throw new UnsupportedOperationException();
	}

	protected void rejectIntention(Path path) {
		this.rejectedPaths.add(path);
	}

	protected void confirmIntention(Path path){
		if(!(this.getAgent().getTruck().isOnConnector() && !path.contains(this.getAgent().getTruck().getConnectorPosition().getConnector()))){
			changeState  = true;
			acceptedPath  = path;
		}
	}

	protected int getHops() {
		return hops;
	}

	protected void increaseHops(){
		this.hops +=5;
	}


	protected void resetTicksLeft(){
		this.ticksLeft = this.hops;
	}


	protected int getTicksLeft(){
		return this.ticksLeft;
	}

	protected void decreaseTicksLeft(){
		this.ticksLeft--;
	}
}
